package com.cstp.manage;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.cstp.entity.Prize;
import com.cstp.entity.PrizeHis;
import com.cstp.exception.ServiceException;
import com.cstp.web.req.PrizeLotteryReq;
import com.cstp.web.req.Yichang365Req;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author watts
 */
@Slf4j
@Component
public class PrizeManage {

    @Resource
    private WxMpManage wxMpManage;

    @Resource
    private StringRedisTemplate template;

    @Value("${wx.yichang365.lotteryUrl}")
    String lotteryUrl;

    @SneakyThrows
    public boolean preCheck(Long id, String userId) {
        log.info("lottery precheck param id:{},openid:{}", id, userId);
        this.check(id, userId);
        Prize prize = new Prize().selectById(id);
        return prize.getNum() > 0;
    }

    private void check(Long id, String userId) {
        //已领取过
        String key = "lottery:" + id + ":" + userId;
        if (Optional.ofNullable(template.hasKey(key)).orElse(false)) {
            throw new ServiceException("一个用户只能抽取一次大礼包/汽车票");
        }
        //数量是否够
        PrizeHis query = new PrizeHis();
        query.setUserId(userId);
        query.setPrizeId(id);
        PrizeHis prizeLog = new PrizeHis().selectOne(new QueryWrapper<>(query));
        if (null != prizeLog) {
            throw new ServiceException("一个用户只能抽取一次大礼包/汽车票");
        }
    }

    @SneakyThrows
    public boolean lottery(PrizeLotteryReq param, String userId) {
        log.info("lottery param :{},openid:{}", JSONUtil.toJsonStr(param), userId);
        //已领取过
        this.check(param.getPrizeId(), userId);
        String key = "lottery:" + param.getPrizeId() + ":" + userId;
        template.opsForValue().set(key, "1");
        param.setUserId(userId);
        Prize prize = new Prize().selectById(param.getPrizeId());
        if (prize.getNum() <= 0) {
            return false;
        }
        //抽奖
        boolean lottery = getLottery(prize.getChance());
        log.info("lottery result :{},openid:{}", lottery, userId);
        if (lottery) {
            Prize p = new Prize();
            p.setId(prize.getId());
            boolean r = prize.update(new LambdaUpdateWrapper<>(p)
                    .set(Prize::getNum, prize.getNum() - 1)
                    .gt(Prize::getNum, 0));
            if (r) {
                PrizeHis prizeHis = new PrizeHis();
                BeanUtil.copyProperties(param, prizeHis);
                prizeHis.setUname(param.getName());
                prizeHis.insert();
                //中奖了调用龙骧巴士同步接口
                if (prize.getType() == 2) {
                    Yichang365Req req = new Yichang365Req();
                    req.setWinners(List.of(Yichang365Req.Winner
                            .builder()
                            .idCard(param.getIdCard())
                            .name(param.getName())
                            .mobile(param.getPhone())
                            .build()));
                    String result = HttpUtil.createPost(lotteryUrl)
                                            .body(JSONUtil.toJsonStr(req), "application/json; charset=utf-8")
                                            .execute()
                                            .body();
                    log.info("send post yichang365 result {}", result);
                }
                //发送消息
                if (prize.getType() == 3) {
                    wxMpManage.sendLotteryMsg(userId, prize.getName());
                }
                return true;
            }
        }
        return false;
    }

    public static boolean getLottery(int chance) {
        int probabilityCount = 100;
        String min = "min";
        String max = "max";
        int tempInt = 0;
        Map<Long, Map<String, Integer>> prizeMap = new HashMap<>(1);
        Map<String, Integer> odMap = new HashMap<>(2);
        odMap.put(min, tempInt);
        tempInt = tempInt + chance;
        odMap.put(max, tempInt);
        prizeMap.put(1L, odMap);
        int index = (int) (Math.random() * probabilityCount);
        Set<Long> prizeIds = prizeMap.keySet();
        for (Long prizesId : prizeIds) {
            Map<String, Integer> oddMap = prizeMap.get(prizesId);
            Integer minNum = oddMap.get(min);
            Integer maxNum = oddMap.get(max);
            if (minNum <= index && maxNum > index) {
                return true;
            }
        }
        return false;
    }
}
